/****************************************************************
 *This file is system_init.c
 ****************************************************************/

#include "include.h"

/****************************************************************
 *This function is system init function,
 *	(1)init system source.
 ****************************************************************/
void system_init(void)
{
    unsigned int temp_i;
    int ret;

    // 打开系统提供的内存映射空间设备文件
    mmap_fd = open("/dev/mem", O_RDWR | O_NDELAY); 

    // 将FPGA提供的AXI-LITE空间 0xa000_0000映射到应用层
    mmap_addr = (unsigned char *)mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, MMAP_ADDR);  

    // 申请FIFO
    for(temp_i = 0; temp_i < _422_CHANNEL_NUM; temp_i ++){
        fifo[temp_i] = pfifo_alloc(_422_FIFO_BUF_LEN);
    }

    // 清空指令缓冲区
    for(temp_i = 0; temp_i < PC_COMMAND_NUM; temp_i ++){
        pc_cmd_data[temp_i].pc_command_code = 0;
        pc_cmd_data[temp_i].pc_command_func = NULL;
    }

    // 初始化相关数据
    for(temp_i = 0; temp_i < MAX_FD_NUM; temp_i ++){
        udp_load_count[temp_i] = 0;
        udp_load_data_p[temp_i] = NULL;
        udp_load_flag[temp_i] = FLAG_INVALID;
        ack_udp_load_flag[temp_i] = FLAG_INVALID;

        udp_upload_count[temp_i] = 0;
        udp_upload_data_p[temp_i] = NULL;
        udp_upload_flag[temp_i] = FLAG_INVALID;
        ack_udp_upload_flag[temp_i] = FLAG_INVALID;

        udp_socket_fd[temp_i] = 0;
        udp_socket_fd_two[temp_i] = 0;
        udp_socket_status[temp_i] = FLAG_INVALID;
    }

    // 填充本板卡处理函数
    hitmc_board_func_int(pc_cmd_data);

    // 建立发送日志线程socket
    if ((sockfd_wr_log = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
        //print build err
        fprintf(stderr,"sockfd_command build failed\n");
    }
    bzero(&server_addr_wr_log,sizeof(server_addr_wr_log));
    server_addr_wr_log.sin_family=AF_INET;
    server_addr_wr_log.sin_addr.s_addr =htonl(WR_SYSLOG_IP);
    server_addr_wr_log.sin_port=htons(WR_SYSLOG_PORT);

    // 建立接收日志socket，并绑定端口
    if ((sockfd_command = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
        //print build err
        fprintf(stderr,"sockfd_command build failed\n");
    }
    bzero(&server_addr_command,sizeof(server_addr_command));
    server_addr_command.sin_family=AF_INET;
    server_addr_command.sin_addr.s_addr =htonl(RECEIVE_SYSLOG_IP);
    server_addr_command.sin_port=htons(RECEIVE_SYSLOG_PORT);
    ret = bind(sockfd_command, (struct sockaddr *)&server_addr_command, sizeof(struct sockaddr)) ;
    if(ret < 0){
        //print bind err
        fprintf(stderr,"sockfd_command bind failed\n");
    }

    // 清空缓冲区
    memset(rev_syslog_buf, 0x0, sizeof(rev_syslog_buf));
}

/*
unsigned char wr_fifo_buf[10 * 1024 * 1240];
unsigned char rd_fifo_buf[10 * 1024 * 1240];
unsigned int  rd_fifo_len = 0, ret_fifo_len = 0;

unsigned int temp_k;

    // 测试FIFO
    for(temp_i = 0; temp_i < 256; temp_i ++){
        wr_fifo_buf[temp_i] = temp_i;
    }
    rd_fifo_len = 0;
    rd_fifo_len = pfifo_len(fifo[0]);
    temp_k = 0;
    while(1){
        // 写入数据
        for(temp_i = 0; temp_i < 50000; temp_i ++){
            pfifo_put(fifo[0], wr_fifo_buf, 100);
        }

        // 读取数据
        rd_fifo_len = pfifo_len(fifo[0]);
        
        for(temp_i = 0; temp_i < rd_fifo_len; temp_i ++){
            rd_fifo_buf[temp_i] = 0;
        }
        
        rd_fifo_buf[0] = 0xaa;
        rd_fifo_buf[100] = 0xaa;
        rd_fifo_buf[102] = 0xaa;
        ret_fifo_len = pfifo_get(fifo[0], rd_fifo_buf, rd_fifo_len);

        // 进行判读
        for(temp_i = 0; temp_i < rd_fifo_len; temp_i ++){
            if(rd_fifo_buf[temp_i] != (temp_i % 100))
            {
                fprintf(stderr,"err temp_i is :%d, rd_fifo_buf[temp_i]: %d\n",temp_k, rd_fifo_buf[temp_i]);
                break;
            }
        }

        temp_k ++;
        if(temp_k > 1000){
#ifdef	TST_CODE_SWITCH
	        fprintf(stderr,"temp_k is :%d\n",temp_k);
#endif
            break;
        }
    }

    while(1){
        sleep(1);
    }
*/

/*

    // 读取测试值
    test_data = 0; 
    //test_data = *(unsigned short *)(mmap_addr + 0x00);
    dev_16bit_read(mmap_addr, 0x00, &test_data);

    // 向自检寄存器填写测试值
    test_data += 10; 
    *(unsigned short *)(mmap_addr + 0x00) = test_data;
    dev_16bit_write(mmap_addr, 0x00, test_data);

    // 读取测试值
    test_data = 0; 
    //test_data = *(unsigned short *)(mmap_addr + 0x00);
    dev_16bit_read(mmap_addr, 0x00, &test_data);

*/

/*
    unsigned char fifo_wr_data[256];
    unsigned char fifo_rd_data[256];
    uint wr_len = 256, rd_len = 0;
    unsigned int temp_k;
    int ret = 0;
   temp_k = 0;
    while(1){
        // 获取FIFO长度
        rd_len = 0;
        rd_len = pfifo_len(fifo);

        // 初始化数据
        for(temp_i = 0; temp_i < 256; temp_i ++){
            fifo_wr_data[temp_i] = temp_i + temp_k;
            fifo_rd_data[temp_i] = 0;
        }

        // 写入数据
        ret = pfifo_put(fifo, fifo_wr_data, 256);
        ret = ret;

        // 获取FIFO长度
        rd_len = 0;
        rd_len = pfifo_len(fifo);

        // 读取数据
        ret = pfifo_get(fifo, fifo_rd_data, 256);
        ret = ret;

        // 获取FIFO长度
        rd_len = 0;
        rd_len = pfifo_len(fifo);

        // 进行数据判读
        for(temp_i = 0; temp_i < 256; temp_i ++){
            if(fifo_wr_data[temp_i] != fifo_rd_data[temp_i]){
                break;
            }
        }

        temp_k ++;
    }
*/
